<?php

namespace app\unify\middleware;

use app\unify\traits\Result;
use ReflectionClass;
use think\Request;

class Validate
{
    use Result;

    /**
     * @throws \ReflectionException
     */
    public function handle(Request $r, $next)
    {
        $module = app()->http->getName();
        $controller = $r->controller();
        $classFullName = "\\app\\{$module}\\controller\\{$controller}";

        if (!class_exists($classFullName)) {
            return $next($r);
        }

        $refClass = new ReflectionClass($classFullName);

        $method = $r->action();
        if (!$refClass->hasMethod($method)) {
            return $next($r);
        }

        $refMethod = new \ReflectionMethod($classFullName, $method);


        $validateAnnotationClassList = $refMethod->getAttributes(\think\annotation\route\Validate::class);
        foreach ($validateAnnotationClassList as $validateAnnotationClass) {
            /**
             * @var $validateAnnotation \think\annotation\route\Validate
             */
            $validateAnnotation = $validateAnnotationClass->newInstance();

            /**
             * @var $validate \think\Validate
             */
            $validate = new $validateAnnotation->value();


            if (!$validate->scene($validateAnnotation->scene ?: '')
                ->batch($validateAnnotation->batch)
                ->message($validateAnnotation->message)
                ->check($r->param())) {
                $error = $validate->getError();
                if (is_array($error)) {
                    $error = implode("\n", array_values($error));
                }
                return self::error($error);
            }

        }


        return $next($r);
    }
}